﻿//using Newtonsoft.Json.Linq;
using System.ComponentModel;
using System.Data;
using System.Reflection;

namespace AutomaticPush.Extension
{
    public static class ListExtension
    {
        /// <summary>        
        ///  将对象属性转换为key-value对        
        /// </summary>    
        /// <param name="o"></param>       
        /// <returns></returns>        
        public static Dictionary<string, object> ToMapProperty<T>(this T o)
        {
            Dictionary<string, object> map = new Dictionary<string, object>();
            Type t = o.GetType();
            PropertyInfo[] pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo p in pi)
            {
                MethodInfo mi = p.GetGetMethod();
                if (mi != null && mi.IsPublic)
                {
                    var value = mi.Invoke(o, new object[] { });
                    if (value == null)
                        continue;
                    map.Add(p.Name, mi.Invoke(o, new object[] { }));
                }
            }
            return map;
        }

        public static Dictionary<string, object> ToMapField<T>(this T o)
        {
            Dictionary<string, object> map = new Dictionary<string, object>();
            Type t = o.GetType();
            FieldInfo[] pi = t.GetFields(BindingFlags.Public | BindingFlags.Instance);
            foreach (FieldInfo p in pi)
            {
                var mi = p.GetValue(o);
                if (mi != null)
                {
                    map.Add(p.Name, mi);
                }
            }
            return map;
        }


        /// <summary>
        /// List数据格式转换为DataTable数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static DataTable ListToDataTable<T>(this List<T> data)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable dataTable = new DataTable();
            for (int i = 0; i < properties.Count; i++)
            {
                PropertyDescriptor property = properties[i];
                dataTable.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
            }
            object[] values = new object[properties.Count];
            foreach (T item in data)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = properties[i].GetValue(item);
                }
                dataTable.Rows.Add(values);
            }
            return dataTable;
        }

        /// <summary>
        ///  DataTable数据格式转换为List数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="table"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static List<T> GetEntityList<T>(this DataTable table)
        {
            List<T> entityList = new List<T>();
            var properties = typeof(T).GetAllProperties().ToLookup(property => property.Name, property => property).ToDictionary(i => i.Key, i => i.First()).Values;

            //循环Datable中的每一行
            foreach (DataRow row in table.Rows)
            {
                //新建Entity
                T entity = (T)Activator.CreateInstance(typeof(T));
                //循环Entity的每一个属性
                foreach (var item in properties)
                {
                    try
                    {
                        //如果DataTable中有列名和属性名一致，则把单元格内容赋值给Entity的该属性
                        if (row.Table.Columns.Contains(item.Name))
                        {
                            //判断null值
                            if (string.IsNullOrEmpty(row[item.Name].ToString()))
                            {
                                item.SetValue(entity, null);
                            }
                            else
                            {
                                var ptype = item.PropertyType;
                                if (ptype.IsNullable())
                                {
                                    ptype = ptype.GenericTypeArguments[0];
                                }
                                //如果是Guid或Guid?类型
                                if (ptype == typeof(Guid))
                                {
                                    if (row[item.Name].GetType() == typeof(byte[]))
                                    {
                                        item.SetValue(entity, new Guid((byte[])row[item.Name]));
                                    }
                                    else
                                        item.SetValue(entity, Guid.Parse(row[item.Name].ToString()));
                                }
                                //如果是enum或enum?类型
                                else if (ptype.IsEnum)
                                {
                                    item.SetValue(entity, Enum.ToObject(ptype, row[item.Name]));
                                }
                                else
                                {
                                    item.SetValue(entity, Convert.ChangeType(row[item.Name], ptype));
                                }

                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                }
                entityList.Add(entity);
            }
            return entityList;
        }

        public static T GetEntity<T>(this DataTable table)
        {
            DataRow row = table.Rows[0];
            var properties = typeof(T).GetAllProperties().ToLookup(property => property.Name, property => property).ToDictionary(i => i.Key, i => i.First()).Values;
            //新建Entity
            T entity = (T)Activator.CreateInstance(typeof(T));
            //循环Entity的每一个属性
            foreach (var item in properties)
            {
                try
                {
                    //如果DataTable中有列名和属性名一致，则把单元格内容赋值给Entity的该属性
                    if (row.Table.Columns.Contains(item.Name))
                    {
                        //判断null值
                        if (string.IsNullOrEmpty(row[item.Name].ToString()))
                        {
                            item.SetValue(entity, null);
                        }
                        else
                        {
                            var ptype = item.PropertyType;
                            if (ptype.IsNullable())
                            {
                                ptype = ptype.GenericTypeArguments[0];
                            }
                            //如果是Guid或Guid?类型
                            if (ptype == typeof(Guid))
                            {
                                item.SetValue(entity, Guid.Parse(row[item.Name].ToString()));
                            }
                            //如果是enum或enum?类型
                            else if (ptype.IsEnum)
                            {
                                item.SetValue(entity, Enum.ToObject(ptype, row[item.Name]));
                            }
                            else
                            {
                                item.SetValue(entity, Convert.ChangeType(row[item.Name], ptype));
                            }

                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
            return entity;

        }

 
    }
}
